/* pc_main.c is small program using the asciiboard API, which is
   designed to run on a PC to render a recorded or generated performance.
   It renders a saved text file in the ASCIIboard format to a .wav output
   file.
   
   Copyright (C) 2014 James Boyle

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include "pc/portsf.h"
#include "asciiboard.h"
#include "pc/pc_main.h"
#include "asciiboard_const.h"
/* debug */
int i;
#include "rpi/ascii_gyro.h"

/* check if C99 is supported on the compiler, for snprintf() */
#if (__STDC_VERSION__ >= 199901L)
#define C99_SUPPORTED
#endif

int main(int argc, char *argv[])
{
	PSF_PROPS properties;
	psf_format out_format;
	int ofd;
	float audio_buffer[BUFFER_SIZE];
	FILE *in_text_file;
	char ch;

	/* sanity check on program arguments */
	if (argc < ARG_COUNT)
	{
		printf("Note: Insufficient arguments.\n");
		printf("Usage: asciiboard <intput filename.txt> ");
		printf("<output filename.wav>\n");
		return 0;
	}

	printf("ASCIIBoard Audio Renderer\n");
	/* open the input text file */
	in_text_file = fopen(argv[ARG_INPUT], "r");
	if (in_text_file == NULL)
	{
		printf("Note: Invalid input text file.\n");
		return 0;
	}

	/* initialise sound file library */
	ofd = INVALID_FILE;
	if (psf_init())
	{
		printf("Error: Unable to start portsf.\n");
		cleanup(ofd);
		return 0;
	}

	/* check file extension of output file */
	out_format = psf_getFormatExt(argv[ARG_OUTPUT]);
	if (out_format == PSF_FMT_UNKNOWN)
	{
		printf("Note: Unrecognised output file format.\n");
		cleanup(ofd);
		return 0;
	}

	/* set up output file properties and create file */
	properties.srate = (int) SRATE;
	properties.chans = 1; /* mono */
	properties.samptype = PSF_SAMP_IEEE_FLOAT;
	properties.format = out_format;
	properties.chformat = (psf_channelformat) out_format;
	ofd = psf_sndCreate(argv[ARG_OUTPUT], &properties, 0, 0,
	                    PSF_CREATE_RDWR);

	asciiboard_init(NULL, audio_buffer, BUFFER_SIZE, process_output,
	                (void *) &ofd, NULL);
	asciiboard_add_processing_func(ascii_through_comments, CRITICAL);
	asciiboard_add_processing_func(gyro_synth, HIGH);
	
	for (;;)
	{
		/* read another character from the file (as char for
		   better portability) */
		ch = fgetc(in_text_file);
		if (ch == EOF)
			break;
		/* process the character */
		asciiboard(ch);
	}

	cleanup(ofd);

	return 0;
}

void process_output(const float *buffer, const int samples, void *args)
{
	int *ofd = (int *) args;

	psf_sndWriteFloatFrames(*ofd, buffer, samples);
}

void cleanup(const int ofd)
{
	if (ofd >= 0)
		psf_sndClose(ofd);
	asciiboard_finish();
	psf_finish();
}
